package hotel.quartz.oversea.job.switchs;

import com.alibaba.fastjson.JSON;
import hotel.base.oversea.constant.CommonConstants;
import hotel.base.oversea.constant.CommonUrlConstants;
import hotel.base.oversea.constant.quartz.UrlSwitchsEnums;
import hotel.base.oversea.utils.DateUtil;
import hotel.base.oversea.utils.Result;
import hotel.quartz.oversea.job.base.BaseJob;
import hotel.quartz.oversea.service.JobAndTriggerService;
import hotel.quartz.oversea.util.JobRestTemplateUtils;
import hotel.quartz.oversea.vo.switchs.ReturnDltOrderInfoVo;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.client.RestTemplate;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  携程订单变化通知-所有订单的变化通知
 * </p>
 *
 * @description: Switchs Hotel Order New Notify Job
 * @author: qiuyy
 * @date: 2020-05-26 13:22
 * @version: V1.0
 */
@Slf4j
public class SwitchHotelOrderGetNotifyJob implements BaseJob {
    private String timestamp = "Shonnj"+String.valueOf(System.currentTimeMillis());

    private String redisKeyNewOrderPageIndex = "switchs-hotel-new-order-notify";
    private String redisKeyNewOrderStartTime = "switchs-hotel-new-order-start-time";
    private Integer beforSecond;//24*60*60;//60*60;//查询条件时间往前推1分钟
    @Autowired
    private JobAndTriggerService jobAndTriggerService;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RestTemplate restTemplate;

    public void setBeforSecond(Integer beforSecond){
        this.beforSecond = beforSecond;
    }

    /**
     *
     * 上游接口：往list_notify 表 插入数据
     *
     * （不操作暂停定时器，一直跑）
     * 每10秒跑一次，24小时不断，接收所有订单通知
     * 定时器初始执行 endTime为当前时间，startTime为往前推一分钟；
     * 后续，每次记录endTime时间，作为下一次的startTime时间，
     * start和end以分为单位，不以秒
     *
     * @param jobExecutionContext
     */
    @Override
    @SneakyThrows
    public void execute(JobExecutionContext jobExecutionContext) {
        //拉取订单主要是根据开始时间和结束时间    redisKeyNewOrderStartTime  ！！  人工更改时间可以改缓存redisKeyNewOrderStartTime
        //redisBeforSecond 表示用来开始时间和结束时间间隔分钟数
        Integer redisBeforSecond = (Integer) redisTemplate.opsForValue().get("SwitchHotelOrderGetNotifyJob_beforSecond");
        if(null != redisBeforSecond){
            setBeforSecond(redisBeforSecond);
        }else{
            setBeforSecond(60);//默认一分钟 60秒
        }
        if(null == redisBeforSecond){
            setBeforSecond(60);//默认一分钟 60秒
        }

        log.info("Switchs Hotel Order New Notify Job {} >>>>>>>> 新订订单接口获取定时器执行时间: {},{}", timestamp, DateUtil.getNowTime(),beforSecond);
        String host = CommonUrlConstants.SWITCHS_HOST;
        String urlMethod = UrlSwitchsEnums.orderNotify.ALL.getValue();
        String url = host+urlMethod;
        requestApi(url);
        log.info("Switchs Hotel Order New Notify Job {} >>>>>>>> 新订订单接口获取定时器结束时间: {},{}",timestamp, DateUtil.getNowTime());
    }

    /**
     * 请求新订订单接口获取定时器接口
     */
    public void requestApi(String url){
        Map params = new HashMap();
        String startTime = getRedisNewOrderNotifyStartTIme();
        String endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());//注意24小时制
        String pageIndex = getRedisNewOrderNotifyPageIndex();
        //params.put("formType","N");不指定类型 接收所有订单
        params.put("startTime",startTime);
        params.put("endTime",endTime);
        params.put("pageIndex",pageIndex);//pageSize不传则默认100
        log.info("Switchs Hotel Order New Notify Job {} 新订订单接口获取定时器进入方法 requestApi:{}",timestamp, JSON.toJSONString(params));
        //发起请求
        Result response = JobRestTemplateUtils.post(url, JSON.toJSONString(params),restTemplate);
        if(response.getCode()== CommonConstants.SUCCESS){
            if(null != response.getData()){
                List<ReturnDltOrderInfoVo> voList = (List<ReturnDltOrderInfoVo>)response.getData();
                if(null != voList && voList.size()>0){
                    int newPageIndex = Integer.valueOf(pageIndex)+1;
                    setRedisNewOrderNotifyPageIndex(String.valueOf(newPageIndex));
                }else{
                    //当前startTime已无下一页数据，将当前endTime作为下一次的startTime(再对该startTime往前推1分钟)，新的endTime都是取当前时间
                    updateTimeRedis(endTime);
                }
            }else{
                //当前startTime已无下一页数据，将当前endTime作为下一次的startTime(再对该startTime往前推1分钟)，新的endTime都是取当前时间
                updateTimeRedis(endTime);
                log.error("Switchs Hotel Order New Notify Job {} 新订订单接口获取定时器 返回data为空: {},{}",timestamp,response, JSON.toJSONString(params));
            }

        }else{
            //当前startTime已无下一页数据，将当前endTime作为下一次的startTime(再对该startTime往前推1分钟)，新的endTime都是取当前时间
            updateTimeRedis(endTime);
            log.error("Switchs Hotel Order New Notify Job {} 新订订单接口获取定时器返回失败: {},{}",timestamp,response, JSON.toJSONString(params));
        }
    }

    private void updateTimeRedis(String endTime) {
        log.info("Switchs Hotel Order New Notify Job {} 新订订单接口获取定时器，无一下页面，重置页码等信息",timestamp);
        deleteRedisNewOrderNotifyPageIndex();
        setRedisNewOrderNotifyStartTIme(endTime);
    }

    private String getRedisNewOrderNotifyPageIndex(){
        String pageIndex = (String)redisTemplate.opsForValue().get(redisKeyNewOrderPageIndex);
        if(null == pageIndex){
            pageIndex = "1";
        }
        return pageIndex;
    }
    private void setRedisNewOrderNotifyPageIndex(String newPageIndex){
        log.error("Switchs Hotel Order New Notify Job {} 新订订单接口获取定时器，存在下一页，更新页码：{}",timestamp,newPageIndex);
        redisTemplate.opsForValue().set(redisKeyNewOrderPageIndex,newPageIndex);
    }
    private void deleteRedisNewOrderNotifyPageIndex(){
        redisTemplate.delete(redisKeyNewOrderPageIndex);
    }
    private String getRedisNewOrderNotifyStartTIme(){
        String startTime = (String)redisTemplate.opsForValue().get(redisKeyNewOrderStartTime);
        log.info("Switchs Hotel Order New Notify Job {} 新订订单接口获取定时器，缓存的上次startTime：{}",startTime);
        if(null != startTime){
            Long diff = hotel.base.oversea.utils.DateUtil.dateDiff(startTime,"min", cn.hutool.core.date.DateUtil.now(),"yyyy-MM-dd HH:mm:ss");
            if(diff>60){
                log.info("Switchs Hotel Order New Notify Job {} 新订订单接口获取定时器，缓存的上次startTime,重置：{},{}",startTime,diff);
                startTime = null;//重置
            }
        }//DateUtil.formatDate 这个是12小时制
        if(null == startTime){
            startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(DateUtil.addSecond(new Date(),-beforSecond));//提前一分钟
        }else{
            startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(DateUtil.addSecond(startTime,-beforSecond));//提前一分钟

        }
        return startTime;
    }
    private void setRedisNewOrderNotifyStartTIme(String time){
        redisTemplate.opsForValue().set(redisKeyNewOrderStartTime,time);
    }

    public static void main(String[] args) {
        System.out.printf("-------- "+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }

}
